/* ****************************************************************************
 *
 * Copyright (c) Microsoft Corporation. 
 *
 * This source code is subject to terms and conditions of the Microsoft Public License. A 
 * copy of the license can be found in the License.html file at the root of this distribution. If 
 * you cannot locate the  Microsoft Public License, please send an email to 
 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
 * by the terms of the Microsoft Public License.
 *
 * You must not remove this notice, or any other, from this software.
 *
 * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
 * PARTICULAR PURPOSE.
 * ***************************************************************************/



#if !defined(AFX_PGLMARKER_H__9A83CD27_4FFD_416E_A765_827D3D49CDD9__INCLUDED_)
#define AFX_PGLMARKER_H__9A83CD27_4FFD_416E_A765_827D3D49CDD9__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <pgl/core/PGLObject.h>
#include <pgl/core/PGLData.h>
#include <pgl/core/PGLText.h>

/*! 
	\defgroup PGLMarkerGroup Markers
	\ingroup PGLLineGroup
*/

/*! \brief Base class for marker objects

\par Common characteristics
	The main characteristics of a marker, besides those inherited from CPGLObject, are:
		- filled/not filled (default is false), see #SetFilled, #IsFilled
		- contoured/not contoured (default is true), see #SetContoured, #IsContoured
		- shadowing (default is false), see #SetShadowing, #IsShadowing
		- the radius in pixels, see #SetRadius, #GetRadius
		- the phase in CCW radians, set #SetPhase, #GetPhase
		- the line width in pixels, see #SetLineWidth, #GetLineWidth
		- the line dashing pattern, see #SetLineDashing, #GetLineDashing. See CPGLLine for more details about dashing patterns.
		- showing values, see below.

\par Showing values

	The coordinates of the points can be shown. This feature is controlled by a CPGLText object. You can access this object
by using #GetTextFormat. The characteristics of the text object are:
	- shown/hidden state, show or hide values,
	- string, string format using classical sprintf syntax, default value is "(%2.2g,%2.2g)"
	- all the classical characteristics of a #CPGLText object.

	By default, when the string is rendered, PGL considers that the \f$x\f$ value comes first and then the \f$y\f$ value, so that the formating string
looks like
\code
	CString str;
	str.Format( m_textFormat.GetString(), x, y);
\endcode
You can invert \f$x\f$ and \f$y\f$ by using #SetXFirst .

 \ingroup PGLMarkerGroup
*/
class PGLCORE_EXT_CLASS CPGLMarker : public CPGLObject  
{
PGL_DECLARE_DYNCREATE(CPGLMarker);
public:
	//! \name Constructors
	//@{
	//! default constructor
	CPGLMarker(const CPGLColor& _color=CPGLColor(), const CPGLColor& _FillColor=CPGLColor(1,1,1,1), double dRadius = 4, bool bFilled = false);
	//! copy construtor
	CPGLMarker(const CPGLMarker& m)	{*this=m;};
	//! assignement constructor
	CPGLMarker& operator = ( const CPGLMarker& m);
	virtual ~CPGLMarker();
	//@}

	//! \name Setters and getters
	//@{
	//! set line width
	void SetLineWidth( double lineWidth)		{	m_dLineWidth = __max( 0, lineWidth ) ;};
	//! return line width
	double GetLineWidth() const					{	return m_dLineWidth;};
	//! set line dashing
	void SetLineDashing( LPCTSTR szLineDashing)	{	m_sLineDashing = szLineDashing;};
	//! return the line dashing
	LPCTSTR GetLineDashing() const				{	return m_sLineDashing;};
	//! sets the marker radius
	virtual void SetRadius( double radius )		{	m_dRadius = __max( 0, radius ); };
	//! return the marker radius
	double GetRadius() const					{	return m_dRadius; };
	//! sets the marker phase
	virtual void SetPhase( double p)			{	m_dPhase = p;};
	//! return the phase
	double GetPhase() const						{	return m_dPhase;};
	//! fills the marker with a brush...
	void SetFilled( bool bFilled = true )		{	m_bFilled = bFilled;};
	//! return the filled state
	bool IsFilled() const						{	return m_bFilled;};
	//! set contoured
	void SetContoured(bool yes = true)			{	m_bContoured = yes;};
	//! return true if outline is shown
	bool IsContoured() const					{	return m_bContoured;};
	//! set shadowing on, default is off
	void SetShadowing( bool on = true)			{	m_bShadowing = true;};
	//! Sets shadowing
	bool IsShadowing() const					{	return m_bShadowing;};
	//@}

	//! \name Text annotations
	//@{
	//! sets if x is renderer before y (default behavior)
	void SetTextXFirst(bool bXFirst)			{	m_bTextXFirst=bXFirst;};
	//! return if x is renderer before y
	bool IsTextXFirst() const					{	return m_bTextXFirst;};
	//! sets the text format
	void SetTextFormat(LPCTSTR szFormat)		{	m_textFormat.SetString(szFormat);};
	//! sets the text format
	void SetTextFormat(const CPGLText& text)	{	m_textFormat=text;};
	//! returns the text format
	CPGLText& GetTextFormat()					{	return m_textFormat;};
	//! returns the text format
	const CPGLText& GetTextFormat() const		{	return m_textFormat;};
	//@}

	//! \name Drawing functions...
	//@{
	//! plotting marker along points...
	virtual void PlotGfx(gfxinterface::CGfxInterface& gfx, CPGLDataPtr pDataX, CPGLDataPtr pDataY);
	//! legend drawing
	virtual void PlotLegendGfx(gfxinterface::CGfxInterface& gfx, float x, float y);
	//@}

	//! \name Scripting methods
	//@{
	//! property enumeration
	enum EMarkerProp
	{
		MarkerPropUnknow,
		MarkerPropRadius,
		MarkerPropPhase,
		MarkerPropLineWidth,
		MarkerPropLineDash,
		MarkerPropContoured,
		MarkerPropShadowing,
		MarkerPropFilled,
		MarkerPropXFirst
	};
	PGL_DECLARE_SCRIPTING(Marker);
	//@}

	//! \name Serialize functions
	//@{
	//! Serialiation to XML
	void SerializeXML(CPGLArchive& ar);

	//! Debuggin functions
	#ifdef _DEBUG
		//! MFC Dump
	    virtual void Dump( CDumpContext& dc ) const;
		//! MFC AssertValid
	    virtual void AssertValid() const;   
	#endif
	//@}

protected:
	//! returns the legend radius
	float GetLegendRadius() const				{	return (float)__min( m_fstLegendRadius, m_dRadius);};
	//! returns ELineType for IGFX
	virtual DWORD GetLineType() const;
private:
	//! \name Attributes
	//@{
	//! line width
	double m_dLineWidth;
	//! dashing
	CString m_sLineDashing;
	//! radius in pixels
	double m_dRadius;
	//! phase in CCW radians
	double m_dPhase;
	//! filled state
	bool m_bFilled;
	//! contoured state
	bool m_bContoured;
	//! shadowing
	bool m_bShadowing;
	//! text format
	CPGLText m_textFormat;
	//! x first
	bool m_bTextXFirst;
	//! maximum legend radius
	static float m_fstLegendRadius;
	//@}
};

PGL_DECLARE_SMARTPTR( CPGLMarker );

#endif // !defined(AFX_PGLMARKER_H__9A83CD27_4FFD_416E_A765_827D3D49CDD9__INCLUDED_)
